#include"VMAC.h"
#include <cmath>

inline int VMAC::get_delay() {
    return this->delay_cycles;
}

void VMAC::input_operands(std::vector<base_operand*>* operands) {
    this->operand_list = operands;
}

inline uint64_t VMAC::read_Reg(int reg_id) {
    return this->RF->get_vec_register_value(reg_id)->at(this->id);
}

inline void VMAC::write_Reg(int reg_id, uint64_t value, int delay) {
    // return set_vec_regsiter_single(reg_id, this->id, value);
    this->res_value = value;
    this->dst_reg_id = reg_id;
    this->delay_cycles = delay;
}

//!ATTENTION: 以下的每一个do_XXX函数内，计算均需要将底层的uint64_t类型数据转换为对应的浮点数类型进行计算，再将结果转换为uint64_t类型存储回寄存器
//!ATTENTION: 64位转换为double，32位转换为float，16位转换为half float
inline uint64_t VMAC::do_VFMULD(int src1_reg_id, int src2_reg_id, int dst_reg_id) {
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    double d_src1 = uint64_to_double(src1);
    double d_src2 = uint64_to_double(src2);
    double d_res = d_src1 * d_src2;
    uint64_t res = double_to_uint64(d_res);
    write_Reg(dst_reg_id, res, 4);
    //!将结果的64位值返回的作用是预留后续的性能分析API，用以获取DSP执行过程中的细粒度数据
    return res;
}


inline uint64_t VMAC::do_VFMULS32(int src1_reg_id, int src2_reg_id, int dst_reg_id) {

    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    float low32_src1 = uint32_to_float(src1 & 0xFFFFFFFF);
    float high32_src1 = uint32_to_float((src1 >> 32) & 0xFFFFFFFF);
    float low32_src2 = uint32_to_float(src2 & 0xFFFFFFFF);
    float high32_src2 = uint32_to_float((src2 >> 32) & 0xFFFFFFFF); //取高、低32位

    float res_low = low32_src1 * low32_src2;
    float res_high =high32_src1 * high32_src2;

    uint32_t res_low_uint = float_to_uint32(res_low);
    uint32_t res_high_uint = float_to_uint32(res_high);

    uint64_t res = (static_cast<uint64_t>(res_high_uint) << 32) | static_cast<uint64_t>(res_low_uint);

    //TODOszy:根据我修改后的api，对每个指令加入其执行延迟
    write_Reg(dst_reg_id, res, 4);
    return res;
}


inline uint64_t VMAC::do_VFMULAD(int src1_reg_id, int src2_reg_id, int src3_reg_id, int dst_reg_id) {
    std::cout << "Entering VMAC::do_VFMULAD" << std::endl;
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t src3 = read_Reg(src3_reg_id);
    double d_src1 = uint64_to_double(src1);
    double d_src2 = uint64_to_double(src2);
    double d_src3 = uint64_to_double(src3);
    std::cout << "VMAC ID " << this->id << " performing VFMULAD in double format with src1: " << d_src1 << ", src2: " << d_src2 << ", src3: " << d_src3 << std::endl;
    uint64_t res = double_to_uint64(d_src1 * d_src2 + d_src3);
    write_Reg(dst_reg_id, res, 6);

    return res;
}


inline uint64_t VMAC::do_VFMULAS32(int src1_reg_id, int src2_reg_id, int src3_reg_id, int dst_reg_id) {

    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t src3 = read_Reg(src3_reg_id);

    float low32_src1 = uint32_to_float(src1 & 0xFFFFFFFF);
    float high32_src1 = uint32_to_float((src1 >> 32) & 0xFFFFFFFF);
    float low32_src2 = uint32_to_float(src2 & 0xFFFFFFFF);
    float high32_src2 = uint32_to_float((src2 >> 32) & 0xFFFFFFFF);
    float low32_src3 = uint32_to_float(src3 & 0xFFFFFFFF);
    float high32_src3 = uint32_to_float((src3 >> 32) & 0xFFFFFFFF); //取高、低32位
    
    float res_low = low32_src1 * low32_src2 + low32_src3;
    float res_high = high32_src1 * high32_src2 + high32_src3;

    uint32_t res_low_uint = float_to_uint32(res_low);
    uint32_t res_high_uint = float_to_uint32(res_high);

    uint64_t res = (static_cast<uint64_t>(res_high_uint) << 32) | static_cast<uint64_t>(res_low_uint);

    write_Reg(dst_reg_id, res, 6);
    return res;
}


inline uint64_t VMAC::do_VFMULBD(int src1_reg_id, int src2_reg_id, int src3_reg_id, int dst_reg_id) {
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t src3 = read_Reg(src3_reg_id);
    double d_src1 = uint64_to_double(src1);
    double d_src2 = uint64_to_double(src2);
    double d_src3 = uint64_to_double(src3);
    uint64_t res = double_to_uint64(d_src1 * d_src2 - d_src3);
    write_Reg(dst_reg_id, res, 6);

    return res;
}

inline uint64_t VMAC::do_VFMULBS32(int src1_reg_id, int src2_reg_id, int src3_reg_id, int dst_reg_id) {
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t src3 = read_Reg(src3_reg_id);


    float low32_src1 = uint32_to_float(src1 & 0xFFFFFFFF);
    float high32_src1 = uint32_to_float((src1 >> 32) & 0xFFFFFFFF);
    float low32_src2 = uint32_to_float(src2 & 0xFFFFFFFF);
    float high32_src2 = uint32_to_float((src2 >> 32) & 0xFFFFFFFF);
    float low32_src3 = uint32_to_float(src3 & 0xFFFFFFFF);
    float high32_src3 = uint32_to_float((src3 >> 32) & 0xFFFFFFFF); //取高、低32位
    
    float res_low = low32_src1 * low32_src2 - low32_src3;
    float res_high = high32_src1 * high32_src2 - high32_src3;

    uint32_t res_low_uint = float_to_uint32(res_low);
    uint32_t res_high_uint = float_to_uint32(res_high);

    uint64_t res = (static_cast<uint64_t>(res_high_uint) << 32) | static_cast<uint64_t>(res_low_uint);

    write_Reg(dst_reg_id, res, 6);
    return res;
}


inline uint64_t VMAC::do_VFDOT32(int src1_reg_id, int src2_reg_id, int dst_reg_id) {

    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t low32_src1 = src1 & 0xFFFFFFFF;
    uint64_t high32_src1 = (src1 >> 32) & 0xFFFFFFFF;
    uint64_t low32_src2 = src2 & 0xFFFFFFFF;
    uint64_t high32_src2 = (src2 >> 32) & 0xFFFFFFFF; //取高、低32位

    float res_f = uint32_to_float(high32_src1) * uint32_to_float(high32_src2) + uint32_to_float(low32_src1) * uint32_to_float(low32_src2);
    uint64_t res = 0;
    std::memcpy(&res, &res_f, sizeof(res)); // 安全转换

    write_Reg(dst_reg_id, res, 6);
    return res;
}


inline uint64_t VMAC::do_VFCREAL32(int src1_reg_id, int src2_reg_id, int dst_reg_id) {

    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t low32_src1 = src1 & 0xFFFFFFFF;
    uint64_t high32_src1 = (src1 >> 32) & 0xFFFFFFFF;
    uint64_t low32_src2 = src2 & 0xFFFFFFFF;
    uint64_t high32_src2 = (src2 >> 32) & 0xFFFFFFFF; //取高、低32位
    float res_f;

    #if ENDIAN == 1
        res_f = uint32_to_float(low32_src1) * uint32_to_float(low32_src2) - uint32_to_float(high32_src1) * uint32_to_float(high32_src2);
    #else
        res_f = uint32_to_float(high32_src1) * uint32_to_float(high32_src2) - uint32_to_float(low32_src1) * uint32_to_float(low32_src2);
    #endif
    uint64_t res = 0;
    std::memcpy(&res, &res_f, sizeof(res)); // 安全转换

    write_Reg(dst_reg_id, res, 6);
    return res;
}


inline uint64_t VMAC::do_VFCIMAG32(int src1_reg_id, int src2_reg_id, int dst_reg_id) {

    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t low32_src1 = src1 & 0xFFFFFFFF;
    uint64_t high32_src1 = (src1 >> 32) & 0xFFFFFFFF;
    uint64_t low32_src2 = src2 & 0xFFFFFFFF;
    uint64_t high32_src2 = (src2 >> 32) & 0xFFFFFFFF; //取高、低32位

    float res_f = uint32_to_float(low32_src1) *  uint32_to_float(high32_src2) + uint32_to_float(high32_src1) * uint32_to_float(low32_src2);
    uint64_t res = 0;
    std::memcpy(&res, &res_f, sizeof(res)); // 安全转换

    write_Reg(dst_reg_id, res, 6);
    return res;
}

//!对于16位半精度浮点数的操作，参考FP16的表示规则进行转换计算
//!由于C++标准库并未直接支持16位浮点数的运算，所以中间计算均使用float完成，最后进行float->fp16的转换
inline uint64_t VMAC::do_VFADDH16(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    float ll_src1 = fp16_to_float(src1 & 0xFFFF);
    float lh_src1 = fp16_to_float((src1 >> 16) & 0xFFFF);
    float hl_src1 = fp16_to_float((src1 >> 32) & 0xFFFF);
    float hh_src1 = fp16_to_float((src1 >> 48) & 0xFFFF);
    float ll_src2 = fp16_to_float(src2 & 0xFFFF);
    float lh_src2 = fp16_to_float((src2 >> 16) & 0xFFFF);
    float hl_src2 = fp16_to_float((src2 >> 32) & 0xFFFF);
    float hh_src2 = fp16_to_float((src2 >> 48) & 0xFFFF); //每16位取一个半精度浮点数


    //!使用uint64_t存储由float计算后转化为uint16_t的结果，用于后续拼接操作
    uint64_t res_hh, res_hl, res_lh, res_ll;
    res_hh = float_to_fp16(hh_src1 + hh_src2);
    res_hl = float_to_fp16(hl_src1 + hl_src2);
    res_lh = float_to_fp16(lh_src1 + lh_src2);
    res_ll = float_to_fp16(ll_src1 + ll_src2);
    
    uint64_t res = ((res_hh & 0xFFFF) << 48) | ((res_hl & 0xFFFF) << 32) | ((res_lh & 0xFFFF) << 16) | (res_ll & 0xFFFF);

    write_Reg(dst_reg_id, res, 4);
    return res;
}

//TODO:子奕把后续所有的浮点操作按我写的示例，将uint64_t与浮点数之间的转换补充完整，注意区分32位float与64位double
//注意16位半精度浮点数的转换请参考我写的do_VFADDH16，并正确使用fp16_to_float与float_to_fp16函数


inline uint64_t VMAC::do_VFSUBH16(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t ll_src1 = src1 & 0xFFFF;
    uint64_t lh_src1 = (src1 >> 16) & 0xFFFF;
    uint64_t hl_src1 = (src1 >> 32) & 0xFFFF;
    uint64_t hh_src1 = (src1 >> 48) & 0xFFFF;
    uint64_t ll_src2 = src2 & 0xFFFF;
    uint64_t lh_src2 = (src2 >> 16) & 0xFFFF;
    uint64_t hl_src2 = (src2 >> 32) & 0xFFFF;
    uint64_t hh_src2 = (src2 >> 48) & 0xFFFF; //每16位取一个半精度浮点数
    
    float res_hh, res_hl, res_lh, res_ll;
    res_hh = fp16_to_float(hh_src2) - fp16_to_float(hh_src1);
    res_hl = fp16_to_float(hl_src2) - fp16_to_float(hl_src1);
    res_lh = fp16_to_float(lh_src2) - fp16_to_float(lh_src1);
    res_ll = fp16_to_float(ll_src2) - fp16_to_float(ll_src1);
    uint64_t res_hh_64, res_hl_64, res_lh_64, res_ll_64;
    res_hh_64 = float_to_fp16(res_hh);
    res_hl_64 = float_to_fp16(res_hl);
    res_lh_64 = float_to_fp16(res_lh);
    res_ll_64 = float_to_fp16(res_ll);

    uint64_t res = (res_hh_64 << 48) | (res_hl_64 << 32) | (res_lh_64 << 16) | res_ll_64;

    write_Reg(dst_reg_id, res, 4);
    return res;
}



inline uint64_t VMAC::do_VFMULH16(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t ll_src1 = src1 & 0xFFFF;
    uint64_t lh_src1 = (src1 >> 16) & 0xFFFF;
    uint64_t hl_src1 = (src1 >> 32) & 0xFFFF;
    uint64_t hh_src1 = (src1 >> 48) & 0xFFFF;
    uint64_t ll_src2 = src2 & 0xFFFF;
    uint64_t lh_src2 = (src2 >> 16) & 0xFFFF;
    uint64_t hl_src2 = (src2 >> 32) & 0xFFFF;
    uint64_t hh_src2 = (src2 >> 48) & 0xFFFF; //每16位取一个半精度浮点数
    
    float res_hh, res_hl, res_lh, res_ll;
    res_hh = fp16_to_float(hh_src1) * fp16_to_float(hh_src2);
    res_hl = fp16_to_float(hl_src1) * fp16_to_float(hl_src2);
    res_lh = fp16_to_float(lh_src1) * fp16_to_float(lh_src2);
    res_ll = fp16_to_float(ll_src1) * fp16_to_float(ll_src2);

    uint64_t res_hh_64, res_hl_64, res_lh_64, res_ll_64;
    res_hh_64 = float_to_fp16(res_hh);
    res_hl_64 = float_to_fp16(res_hl);
    res_lh_64 = float_to_fp16(res_lh);
    res_ll_64 = float_to_fp16(res_ll);
    
    uint64_t res = ((res_hh_64 & 0xFFFF) << 48) | ((res_hl_64 & 0xFFFF) << 32) | ((res_lh_64 & 0xFFFF) << 16) | (res_ll_64 & 0xFFFF);

    write_Reg(dst_reg_id, res, 4);
    return res;
}


inline uint64_t VMAC::do_VFMULAH16(int src1_reg_id, int src2_reg_id, int src3_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t src3 = read_Reg(src3_reg_id);

    uint64_t ll_src1 = src1 & 0xFFFF;
    uint64_t lh_src1 = (src1 >> 16) & 0xFFFF;
    uint64_t hl_src1 = (src1 >> 32) & 0xFFFF;
    uint64_t hh_src1 = (src1 >> 48) & 0xFFFF;
    uint64_t ll_src2 = src2 & 0xFFFF;
    uint64_t lh_src2 = (src2 >> 16) & 0xFFFF;
    uint64_t hl_src2 = (src2 >> 32) & 0xFFFF;
    uint64_t hh_src2 = (src2 >> 48) & 0xFFFF;
    uint64_t ll_src3 = src3 & 0xFFFF;
    uint64_t lh_src3 = (src3 >> 16) & 0xFFFF;
    uint64_t hl_src3 = (src3 >> 32) & 0xFFFF;
    uint64_t hh_src3 = (src3 >> 48) & 0xFFFF; //每16位取一个半精度浮点数
    
    float res_hh, res_hl, res_lh, res_ll;
    res_hh = fp16_to_float(hh_src1) * fp16_to_float(hh_src2) + fp16_to_float(hh_src3);
    res_hl = fp16_to_float(hl_src1) * fp16_to_float(hl_src2) + fp16_to_float(hl_src3);
    res_lh = fp16_to_float(lh_src1) * fp16_to_float(lh_src2) + fp16_to_float(lh_src3);
    res_ll = fp16_to_float(ll_src1) * fp16_to_float(ll_src2) + fp16_to_float(ll_src3);
    
    uint64_t res_hh_64, res_hl_64, res_lh_64, res_ll_64;
    res_hh_64 = float_to_fp16(res_hh);
    res_hl_64 = float_to_fp16(res_hl);
    res_lh_64 = float_to_fp16(res_lh);
    res_ll_64 = float_to_fp16(res_ll);

    uint64_t res = ((res_hh_64 & 0xFFFF) << 48) | ((res_hl_64 & 0xFFFF) << 32) | ((res_lh_64 & 0xFFFF) << 16) | (res_ll_64 & 0xFFFF);

    write_Reg(dst_reg_id, res, 6);
    return res;
}


inline uint64_t VMAC::do_VFMULBH16(int src1_reg_id, int src2_reg_id, int src3_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t src3 = read_Reg(src3_reg_id);

    uint64_t ll_src1 = src1 & 0xFFFF;
    uint64_t lh_src1 = (src1 >> 16) & 0xFFFF;
    uint64_t hl_src1 = (src1 >> 32) & 0xFFFF;
    uint64_t hh_src1 = (src1 >> 48) & 0xFFFF;
    uint64_t ll_src2 = src2 & 0xFFFF;
    uint64_t lh_src2 = (src2 >> 16) & 0xFFFF;
    uint64_t hl_src2 = (src2 >> 32) & 0xFFFF;
    uint64_t hh_src2 = (src2 >> 48) & 0xFFFF;
    uint64_t ll_src3 = src3 & 0xFFFF;
    uint64_t lh_src3 = (src3 >> 16) & 0xFFFF;
    uint64_t hl_src3 = (src3 >> 32) & 0xFFFF;
    uint64_t hh_src3 = (src3 >> 48) & 0xFFFF; //每16位取一个半精度浮点数
    
    float res_hh, res_hl, res_lh, res_ll;
    res_hh = float_to_fp16(hh_src1) * float_to_fp16(hh_src2) - float_to_fp16(hh_src3);
    res_hl = float_to_fp16(hl_src1) * float_to_fp16(hl_src2) - float_to_fp16(hl_src3);
    res_lh = float_to_fp16(lh_src1) * float_to_fp16(lh_src2) - float_to_fp16(lh_src3);
    res_ll = float_to_fp16(ll_src1) * float_to_fp16(ll_src2) - float_to_fp16(ll_src3);

    uint64_t res_hh_64, res_hl_64, res_lh_64, res_ll_64;
    res_hh_64 = float_to_fp16(res_hh);
    res_hl_64 = float_to_fp16(res_hl);
    res_lh_64 = float_to_fp16(res_lh);
    res_ll_64 = float_to_fp16(res_ll);
    
    uint64_t res = ((res_hh_64 & 0xFFFF) << 48) | ((res_hl_64 & 0xFFFF) << 32) | ((res_lh_64 & 0xFFFF) << 16) | (res_ll_64 & 0xFFFF);

    write_Reg(dst_reg_id, res, 6);
    return res;
}


inline uint64_t VMAC::do_VFCMPEH16(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t ll_src1 = src1 & 0xFFFF;
    uint64_t lh_src1 = (src1 >> 16) & 0xFFFF;
    uint64_t hl_src1 = (src1 >> 32) & 0xFFFF;
    uint64_t hh_src1 = (src1 >> 48) & 0xFFFF;
    uint64_t ll_src2 = src2 & 0xFFFF;
    uint64_t lh_src2 = (src2 >> 16) & 0xFFFF;
    uint64_t hl_src2 = (src2 >> 32) & 0xFFFF;
    uint64_t hh_src2 = (src2 >> 48) & 0xFFFF; //每16位取一个半精度浮点数
    
    uint64_t res_hh, res_hl, res_lh, res_ll;
    if (hh_src1 == hh_src2){
        res_hh = 0001;
    }else if (hl_src1 == hl_src2){
        res_hl = 0001;
    }else if (lh_src1 == lh_src2){
        res_lh = 0001;
    }else if (ll_src1 == ll_src2){
        res_ll = 0001;
    }
    
    uint64_t res = (res_hh << 12) | (res_hl << 8) | (res_lh  << 4) | res_ll;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFCMPGH16(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t ll_src1 = src1 & 0xFFFF;
    uint64_t lh_src1 = (src1 >> 16) & 0xFFFF;
    uint64_t hl_src1 = (src1 >> 32) & 0xFFFF;
    uint64_t hh_src1 = (src1 >> 48) & 0xFFFF;
    uint64_t ll_src2 = src2 & 0xFFFF;
    uint64_t lh_src2 = (src2 >> 16) & 0xFFFF;
    uint64_t hl_src2 = (src2 >> 32) & 0xFFFF;
    uint64_t hh_src2 = (src2 >> 48) & 0xFFFF; //每16位取一个半精度浮点数
    
    uint64_t res_hh, res_hl, res_lh, res_ll;
    if (hh_src2 > hh_src1){
        res_hh = 0001;
    }else if (hl_src2 > hl_src1){
        res_hl = 0001;
    }else if (lh_src2 > lh_src1){
        res_lh = 0001;
    }else if (ll_src2 > ll_src1){
        res_ll = 0001;
    }
    
    
    uint64_t res = (res_hh << 12) | (res_hl << 8) | (res_lh  << 4) | res_ll;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFCMPLH16(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t ll_src1 = src1 & 0xFFFF;
    uint64_t lh_src1 = (src1 >> 16) & 0xFFFF;
    uint64_t hl_src1 = (src1 >> 32) & 0xFFFF;
    uint64_t hh_src1 = (src1 >> 48) & 0xFFFF;
    uint64_t ll_src2 = src2 & 0xFFFF;
    uint64_t lh_src2 = (src2 >> 16) & 0xFFFF;
    uint64_t hl_src2 = (src2 >> 32) & 0xFFFF;
    uint64_t hh_src2 = (src2 >> 48) & 0xFFFF; //每16位取一个半精度浮点数
    
    uint64_t res_hh, res_hl, res_lh, res_ll;
    if (hh_src2 < hh_src1){
        res_hh = 0001;
    }else if (hl_src2 < hl_src1){
        res_hl = 0001;
    }else if (lh_src2 < lh_src1){
        res_lh = 0001;
    }else if (ll_src2 < ll_src1){
        res_ll = 0001;
    }
    
    
    uint64_t res = (res_hh << 12) | (res_hl << 8) | (res_lh  << 4) | res_ll;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFHINT16(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t ll_src = src & 0xFFFF;
    uint64_t lh_src = (src >> 16) & 0xFFFF;
    uint64_t hl_src = (src >> 32) & 0xFFFF;
    uint64_t hh_src = (src >> 48) & 0xFFFF; //每16位取一个半精度浮点数

    float ll_src_f = fp16_to_float(ll_src);
    float lh_src_f = fp16_to_float(lh_src);
    float hl_src_f = fp16_to_float(hl_src);
    float hh_src_f = fp16_to_float(hh_src);

    uint64_t res_hh = static_cast<uint64_t>(static_cast<int16_t>(std::round(hh_src_f)));
    uint64_t res_hl = static_cast<uint64_t>(static_cast<int16_t>(std::round(hl_src_f)));
    uint64_t res_lh = static_cast<uint64_t>(static_cast<int16_t>(std::round(lh_src_f)));
    uint64_t res_ll = static_cast<uint64_t>(static_cast<int16_t>(std::round(ll_src_f)));
    
    uint64_t res = (res_hh << 48) | (res_hl << 32) | (res_lh << 16) | res_ll;

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFHTRU16(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t ll_src = src & 0xFFFF;
    uint64_t lh_src = (src >> 16) & 0xFFFF;
    uint64_t hl_src = (src >> 32) & 0xFFFF;
    uint64_t hh_src = (src >> 48) & 0xFFFF; //每16位取一个半精度浮点数
    
    uint64_t res_hh, res_hl, res_lh, res_ll;
    res_hh = static_cast<uint64_t>(std::floor(fp16_to_float(hh_src)));
    res_hl = static_cast<uint64_t>(std::floor(fp16_to_float(hl_src)));
    res_lh = static_cast<uint64_t>(std::floor(fp16_to_float(lh_src)));
    res_ll = static_cast<uint64_t>(std::floor(fp16_to_float(ll_src)));
    
    uint64_t res = ((res_hh & 0xFFFF) << 48) | ((res_hl & 0xFFFF) << 32) | ((res_lh & 0xFFFF) << 16) | (res_ll & 0xFFFF);

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFINTH16(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    int16_t ll_src = static_cast<uint16_t>(src & 0xFFFF);
    int16_t lh_src = static_cast<uint16_t>((src >> 16) & 0xFFFF);
    int16_t hl_src = static_cast<uint16_t>((src >> 32) & 0xFFFF);
    int16_t hh_src = static_cast<uint16_t>((src >> 48) & 0xFFFF); //每16位取一个半精度浮点数
    
    uint64_t res_hh, res_hl, res_lh, res_ll;
    res_hh = static_cast<uint64_t>(float_to_fp16(int16_to_float(hh_src)));
    res_hl = static_cast<uint64_t>(float_to_fp16(int16_to_float(hl_src)));
    res_lh = static_cast<uint64_t>(float_to_fp16(int16_to_float(lh_src)));
    res_ll = static_cast<uint64_t>(float_to_fp16(int16_to_float(ll_src)));
    
    uint64_t res = (res_hh << 48) | (res_hl << 32) | (res_lh << 16) | res_ll;

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFINTHU16(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t ll_src = src & 0xFFFF;
    uint64_t lh_src = (src >> 16) & 0xFFFF;
    uint64_t hl_src = (src >> 32) & 0xFFFF;
    uint64_t hh_src = (src >> 48) & 0xFFFF;//每16位取一个半精度浮点数
    
    uint64_t res_hh, res_hl, res_lh, res_ll;
    res_hh = float_to_fp16(fp16_to_float(hh_src));
    res_hl = float_to_fp16(fp16_to_float(hl_src));
    res_lh = float_to_fp16(fp16_to_float(lh_src));
    res_ll = float_to_fp16(fp16_to_float(ll_src));
    
    uint64_t res = (res_hh << 48) | (res_hl << 32) | (res_lh << 16) | res_ll;

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFSPHP16(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t low32_src1 = src1 & 0xFFFFFFFF;
    uint64_t high32_src1 = (src1 >> 32) & 0xFFFFFFFF;
    uint64_t low32_src2 = src2 & 0xFFFFFFFF;
    uint64_t high32_src2 = (src2 >> 32) & 0xFFFFFFFF;
    
    uint64_t res_hh, res_hl, res_lh, res_ll;
    res_hh = float_to_fp16(uint32_to_float(high32_src2));
    res_hl = float_to_fp16(uint32_to_float(low32_src2));
    res_lh = float_to_fp16(uint32_to_float(high32_src1));
    res_ll = float_to_fp16(uint32_to_float(low32_src1));
    
    uint64_t res = ((res_hh & 0xFFFF) << 48) | ((res_hl & 0xFFFF) << 32) | ((res_lh & 0xFFFF) << 16) | (res_ll & 0xFFFF);

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFHPSP16L(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t ll_src = src & 0xFFFF;
    uint64_t lh_src = (src >> 16) & 0xFFFF;//低半字中，每16位取一个半精度浮点数
 
    
    uint64_t res_high, res_low;
    res_high = float_to_uint32(fp16_to_float(lh_src));
    res_low = float_to_uint32(fp16_to_float(ll_src));
    
    uint64_t res = res_high << 32 | res_low;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFHPSP16H(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t hl_src = (src >> 32) & 0xFFFF;
    uint64_t hh_src = (src >> 48) & 0xFFFF; //高半字中，每16位取一个半精度浮点数
 
    
    uint64_t res_high, res_low;
    res_high = float_to_uint32(fp16_to_float(hh_src));
    res_low = float_to_uint32(static_cast<float>(hl_src));
    
    uint64_t res = res_high << 32 | res_low;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFMANH16(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint16_t ll_src = static_cast<uint16_t>(src & 0xFFFF);
    uint16_t lh_src = static_cast<uint16_t>((src >> 16) & 0xFFFF);
    uint16_t hl_src = static_cast<uint16_t>((src >> 32) & 0xFFFF);
    uint16_t hh_src = static_cast<uint16_t>((src >> 48) & 0xFFFF); //每16位取一个半精度浮点数

    uint64_t res_hh, res_hl, res_lh, res_ll;
    res_hh = fraction_16(hh_src);
    res_hl = fraction_16(hl_src);
    res_lh = fraction_16(lh_src);
    res_ll = fraction_16(ll_src);

    uint64_t res = ((res_hh & 0xFFFF) << 48) | ((res_hl & 0xFFFF) << 32) | ((res_lh & 0xFFFF) << 16) | (res_ll & 0xFFFF);

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFLOGH16(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint16_t ll_src = static_cast<uint16_t>(src & 0xFFFF);
    uint16_t lh_src = static_cast<uint16_t>((src >> 16) & 0xFFFF);
    uint16_t hl_src = static_cast<uint16_t>((src >> 32) & 0xFFFF);
    uint16_t hh_src = static_cast<uint16_t>((src >> 48) & 0xFFFF); //每16位取一个半精度浮点数

    uint64_t res_ll, res_lh, res_hl, res_hh;
    res_ll = exponent(ll_src);
    res_lh = exponent(lh_src);
    res_hl = exponent(hl_src);
    res_hh = exponent(hh_src);

    uint64_t res = ((res_hh & 0xFFFF) << 48) | ((res_hl & 0xFFFF) << 32) | ((res_lh & 0xFFFF) << 16) | (res_ll & 0xFFFF);

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFABSH16(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint16_t ll_src = static_cast<uint16_t>(src & 0xFFFF);
    uint16_t lh_src = static_cast<uint16_t>((src >> 16) & 0xFFFF);
    uint16_t hl_src = static_cast<uint16_t>((src >> 32) & 0xFFFF);
    uint16_t hh_src = static_cast<uint16_t>((src >> 48) & 0xFFFF); //每16位取一个半精度浮点数

    float res_ll_f, res_lh_f, res_hl_f, res_hh_f;
    res_ll_f = fp16_to_float(ll_src);
    res_lh_f = fp16_to_float(lh_src);
    res_hl_f = fp16_to_float(hl_src);
    res_hh_f = fp16_to_float(hh_src);

    uint64_t res_ll, res_lh, res_hl, res_hh;
    res_ll = float_to_fp16(fabs(res_ll_f));
    res_lh = float_to_fp16(fabs(res_lh_f));
    res_hl = float_to_fp16(fabs(res_hl_f));
    res_hh = float_to_fp16(fabs(res_hh_f));

    uint64_t res = ((res_hh & 0xFFFF) << 48) | ((res_hl & 0xFFFF) << 32) | ((res_lh & 0xFFFF) << 16) | (res_ll & 0xFFFF);

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFMAX16(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t ll_src1 = src1 & 0xFFFF;
    uint64_t lh_src1 = (src1 >> 16) & 0xFFFF;
    uint64_t hl_src1 = (src1 >> 32) & 0xFFFF;
    uint64_t hh_src1 = (src1 >> 48) & 0xFFFF; 
    uint64_t ll_src2 = src2 & 0xFFFF;
    uint64_t lh_src2 = (src2 >> 16) & 0xFFFF;
    uint64_t hl_src2 = (src2 >> 32) & 0xFFFF;
    uint64_t hh_src2 = (src2 >> 48) & 0xFFFF;//每16位取一个半精度浮点数

    uint64_t res_ll, res_lh, res_hl, res_hh;

    if(fp16_to_float(ll_src1) > fp16_to_float(ll_src2)){
        res_ll = ll_src1;
    }else{
        res_ll = ll_src2;
    }
    if(fp16_to_float(lh_src1) > fp16_to_float(lh_src2)){
        res_lh = lh_src1;
    }else{
        res_lh = lh_src2;
    }
    if(fp16_to_float(hl_src1) > fp16_to_float(hl_src2)){
        res_hl = hl_src1;
    }else{
        res_hl = hl_src2;
    }
    if(fp16_to_float(hh_src1) > fp16_to_float(hh_src2)){
        res_hh = hh_src1;
    }else{
        res_hh = hh_src2;
    }

    uint64_t res = ((res_hh & 0xFFFF) << 48) | ((res_hl & 0xFFFF) << 32) | ((res_lh & 0xFFFF) << 16) | (res_ll & 0xFFFF);

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFEXTS32L(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t low_src = src & 0xFFFFFFFF;

    uint64_t res = (low_src << 32) | low_src;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFEXTS32H(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t high_src = (src >> 32) & 0xFFFFFFFF; 

    uint64_t res = (high_src << 32) | high_src;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFEXTH16LL(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t ll_src = src & 0xFFFF; 

    uint64_t res = ((ll_src << 48) | (ll_src << 32) | (ll_src << 16) | ll_src);

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFEXTH16LH(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t lh_src = (src >> 16) & 0xFFFF; 

    uint64_t res = ((lh_src << 48) | (lh_src << 32) | (lh_src << 16) | lh_src);

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFEXTH16HL(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t hl_src = (src >> 32) & 0xFFFF; 

    uint64_t res = ((hl_src << 48) | (hl_src << 32) | (hl_src << 16) | hl_src);

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFEXTH16HH(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t hh_src = (src >> 48) & 0xFFFF; 

    uint64_t res = ((hh_src << 48) | (hh_src << 32) | (hh_src << 16) | hh_src);

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VMOV(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);
    uint64_t res = src;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VMOVI(uint64_t imm, int dst_reg_id){
    uint64_t res = imm;

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFCMPED(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t res;

    if(src1 == src2){
        res = 1;
    }else{
        res = 0;
    }

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFCMPES32(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t low32_src1 = src1 & 0xFFFFFFFF;
    uint64_t high32_src1 = (src1 >> 32) & 0xFFFFFFFF;
    uint64_t low32_src2 = src2 & 0xFFFFFFFF;
    uint64_t high32_src2 = (src2 >> 32) & 0xFFFFFFFF;

    uint64_t low_res, high_res;
    if(low32_src1 == low32_src2){
        low_res = 1;
    }else{
        low_res = 0;
    }
    if(high32_src1 == high32_src2){
        high_res = 1;
    }else{
        high_res = 0;
    }

    uint64_t res = high_res << 32 | low_res;
    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFCMPGD(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t res;

    double src1_d = uint64_to_double(src1);
    double src2_d = uint64_to_double(src2);

    if(src1_d > src2_d){
        res = 1;
    }else{
        res = 0;
    }

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFCMPGS32(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t low32_src1 = src1 & 0xFFFFFFFF;
    uint64_t high32_src1 = (src1 >> 32) & 0xFFFFFFFF;
    uint64_t low32_src2 = src2 & 0xFFFFFFFF;
    uint64_t high32_src2 = (src2 >> 32) & 0xFFFFFFFF; //取高、低32位

    float low32_src1_f = uint32_to_float(low32_src1);
    float high32_src1_f = uint32_to_float(high32_src1);
    float low32_src2_f = uint32_to_float(low32_src2);
    float high32_src2_f = uint32_to_float(high32_src2); //转换为单精度浮点数进行比较

    uint64_t low_res, high_res;
    if(low32_src1_f > low32_src2_f){
        low_res = 1;
    }else{
        low_res = 0;
    }
    if(high32_src1_f > high32_src2_f){
        high_res = 1;
    }else{
        high_res = 0;
    }

    uint64_t res = high_res << 32 | low_res;
    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFCMPLD(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    uint64_t res;

    double src1_d = uint64_to_double(src1);
    double src2_d = uint64_to_double(src2);

    if(src1_d < src2_d){
        res = 1;
    }else{
        res = 0;
    }

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFCMPLS32(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);

    uint64_t low32_src1 = src1 & 0xFFFFFFFF;
    uint64_t high32_src1 = (src1 >> 32) & 0xFFFFFFFF;
    uint64_t low32_src2 = src2 & 0xFFFFFFFF;
    uint64_t high32_src2 = (src2 >> 32) & 0xFFFFFFFF; //取高、低32位

    float low32_src1_f = uint32_to_float(low32_src1);
    float high32_src1_f = uint32_to_float(high32_src1);
    float low32_src2_f = uint32_to_float(low32_src2);
    float high32_src2_f = uint32_to_float(high32_src2); //转换为单精度浮点数进行比较

    uint64_t low_res, high_res;
    if(low32_src1_f < low32_src2_f){
        low_res = 1;
    }else{
        low_res = 0;
    }
    if(high32_src1_f < high32_src2_f){
        high_res = 1;
    }else{
        high_res = 0;
    }

    uint64_t res = high_res << 32 | low_res;
    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFDINT(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);
    uint64_t res = double_to_int64(std::round(uint64_to_double(src)));

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFSINT32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint32_t low32_src = src & 0xFFFFFFFF;
    uint32_t high32_src = (src >> 32) & 0xFFFFFFFF;

    float low32_src_f = uint32_to_float(low32_src);
    float high32_src_f = uint32_to_float(high32_src);

    uint64_t low_res = float_to_int32(std::round(low32_src_f));
    uint64_t high_res = float_to_int32(std::round(high32_src_f));
    uint64_t res = (high_res << 32) | low_res;

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFDTRU(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);
    uint64_t res = int64_to_double(static_cast<int64_t>(std::floor(src)));

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFSTRU32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t low32_src = src & 0xFFFFFFFF;
    uint64_t high32_src = (src >> 32) & 0xFFFFFFFF;

    int32_t low_res, high_res;
    low_res =  float_to_int32(std::floor(uint32_to_float(low32_src)));
    high_res =  float_to_int32(std::floor(uint32_to_float(high32_src)));

    uint64_t res = static_cast<uint64_t>(high_res) << 32 | static_cast<uint64_t>(low_res);

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFINTD(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t res = double_to_uint64(int64_to_double(src));

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFINTDU(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t res = double_to_uint64(uint64_to_double(src));

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFINTS32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t low32_src = src & 0xFFFFFFFF;
    uint64_t high32_src = (src >> 32) & 0xFFFFFFFF;

    uint64_t low_res, high_res;
    low_res = float_to_uint32(int32_to_float(low32_src));
    high_res =  float_to_uint32(int32_to_float(high32_src));

    uint64_t res = (high_res << 32) | low_res;

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFINTSU32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    float low_src = uint32_to_float(src & 0xFFFFFFFF);
    float high_src = uint32_to_float((src >> 32) & 0xFFFFFFFF);

    uint64_t low_res, high_res;
    low_res =  float_to_uint32(low_src);
    high_res =  float_to_uint32(high_src);

    uint64_t res = (high_res << 32) | low_res;

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFDPSP32(int src1_reg_id, int src2_reg_id, int dst_reg_id){
    uint64_t src1 = read_Reg(src1_reg_id);
    uint64_t src2 = read_Reg(src2_reg_id);
    
    uint64_t res;
    uint64_t low_res, high_res;

    low_res = float_to_uint32(uint64_to_float(src1));
    high_res = float_to_uint32(uint64_to_float(src2));
    res = (high_res << 32) | low_res;

    write_Reg(dst_reg_id, res, 3);
    return res;
}


inline uint64_t VMAC::do_VFSPDP32T(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);


    uint64_t low32_src = src & 0xFFFFFFFF;

    uint64_t res = double_to_uint64(float_to_double(uint32_to_float(low32_src)));

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFSPHDP32T(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t high32_src = (src >> 32) & 0xFFFFFFFF;

    uint64_t res = double_to_uint64(float_to_double(uint32_to_float(high32_src)));

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFMAND(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);
    
    uint64_t sign = (src >> 63) & 0x1; //提取符号位
    uint64_t mantissa = (src & 0x000FFFFFFFFFFFFF) | 0x0010000000000000; // 提取尾数（包含隐藏位）
    uint64_t res = -((sign << 63) | (mantissa << 10)); // 组合符号位和尾数，并取补码

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFMANS32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t low32_src = src & 0xFFFFFFFF;
    uint64_t high32_src = (src >> 32) & 0xFFFFFFFF;  
    
    uint64_t low_result = fraction_32(low32_src);
    uint64_t high_result = fraction_32(high32_src);

    // 将两个32位结果组合成一个64位结果
    uint64_t res = (high_result << 32) | low_result & 0xFFFFFFFF;
   
    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFLOGD(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);
    
    uint64_t exponent = (src >> 52) & 0x7FF;

        
    uint64_t res = static_cast<int64_t>(exponent) - 1023; // 减去1023（双精度浮点数的指数偏移量）

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFLOGS32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint32_t low32_src = uint32_to_float(static_cast<uint32_t>(src & 0xFFFFFFFF));
    uint32_t high32_src = uint32_to_float(static_cast<uint32_t>((src >> 32) & 0xFFFFFFFF));
    
    uint32_t exponent_low = (src >> 23) & 0xFF;
    uint32_t exponent_high = (src >> 23) & 0xFF;
        
    uint64_t res_low = static_cast<int64_t>(exponent_low) - 127;
    uint64_t res_high = static_cast<int64_t>(exponent_low) - 127;

    uint64_t res = (res_high << 32) | (res_low & 0xFFFFFFFF);   

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFABSD(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);
    double src_d = uint64_to_double(src);

    uint64_t res = double_to_uint64(std::abs(src_d));   

    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFABSS32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t low32_src = src & 0xFFFFFFFF;
    uint64_t high32_src = (src >> 32) & 0xFFFFFFFF;

    uint64_t res_low = float_to_uint32(std::abs(uint32_to_float(low32_src)));
    uint64_t res_high = float_to_uint32(std::abs(uint32_to_float(high32_src)));

    uint64_t res = (res_high << 32) | (res_low & 0xFFFFFFFF);
   
    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFRSQD(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);
    double src_d = uint64_to_double(src);

    uint64_t res = double_to_uint64(sqrcp(src_d));
   
    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFRSQS32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t low32_src = src & 0xFFFFFFFF;
    uint64_t high32_src = (src >> 32) & 0xFFFFFFFF;

    float res_low = 1.0f / std::sqrt(uint32_to_float(low32_src));
    float res_high = 1.0f / std::sqrt(uint32_to_float(high32_src));
    uint64_t res = static_cast<uint64_t>(float_to_uint32(res_high)) << 32 | static_cast<uint64_t>(float_to_uint32(res_low) & 0xFFFFFFFF);
   
    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFRCPD(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t res = double_to_uint64(1.0 / (uint64_to_double(src)));
   
    write_Reg(dst_reg_id, res, 1);
    return res;
}


inline uint64_t VMAC::do_VFRCPS32(int src_reg_id, int dst_reg_id){
    uint64_t src = read_Reg(src_reg_id);

    uint64_t low32_src = src & 0xFFFFFFFF;
    uint64_t high32_src = (src >> 32) & 0xFFFFFFFF;

    float res_low = 1.0f / uint32_to_float(low32_src);
    float res_high = 1.0f / uint32_to_float(high32_src);
    uint64_t res = (static_cast<uint64_t>(float_to_uint32(res_high)) << 32 | static_cast<uint64_t>((float_to_uint32(res_low) & 0xFFFFFFFF)));
   
    write_Reg(dst_reg_id, res, 1);
    return res;
}

write_req_info_reg  VMAC::upload_write_msg() {
    write_req_info_reg res;
    res.value = this->res_value;
    res.reg_id = this->dst_reg_id;
    res.delay = this->delay_cycles;
    return res;
}

uint64_t VMAC::Execute(instruction* vmac_instr) {
    //TODO:这里在跟路哥确认后，修改为具体的VMAC执行计算的逻辑
    //TODO:是否需要读取VIEU的相关指令操作，再决定vmac执行的情况？
    //!需要注意VMAC模块并不只执行乘加操作，需要输入指令来确定执行的结果
    // return (this->src_1 * this->src_2 + this->src_3);
    switch (vmac_instr->get_opcode()) {
        case VFMULD:
            return do_VFMULD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());                          
        case VFMULS32:
            return do_VFMULS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFMULAD:
            return do_VFMULAD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id(),
                                        static_cast<register_operand*>(vmac_instr->get_operands(3))->get_reg_id());
        case VFMULAS32:
            return do_VFMULAS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id(),
                                        static_cast<register_operand*>(vmac_instr->get_operands(3))->get_reg_id());                         
        case VFMULBD:
            return do_VFMULBD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id(),
                                        static_cast<register_operand*>(vmac_instr->get_operands(3))->get_reg_id());                       
        case VFMULBS32:
            return do_VFMULBS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id(),
                                        static_cast<register_operand*>(vmac_instr->get_operands(3))->get_reg_id());                      
        case VFDOT32:
            return do_VFDOT32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());              
        case VFCREAL32:
            return do_VFCREAL32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFCIMAG32:
            return do_VFCIMAG32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFADDH16:
            return do_VFADDH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFSUBH16:
            return do_VFSUBH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFMULH16:
            return do_VFMULH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFMULAH16:
            return do_VFMULAH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id(),
                                        static_cast<register_operand*>(vmac_instr->get_operands(3))->get_reg_id());
        case VFMULBH16:
            return do_VFMULBH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id(),
                                        static_cast<register_operand*>(vmac_instr->get_operands(3))->get_reg_id());
        case VFCMPEH16:
            return do_VFCMPEH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFCMPGH16:
            return do_VFCMPGH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFCMPLH16:
            return do_VFCMPLH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFHINT16:
            return do_VFHINT16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFHTRU16:
            return do_VFHTRU16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFINTH16:
            return do_VFINTH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFINTHU16:
            return do_VFINTHU16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFSPHP16:
            return do_VFSPHP16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFHPSP16L:
            return do_VFHPSP16L(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFHPSP16H:
            return do_VFHPSP16H(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFMANH16:
            return do_VFMANH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFLOGH16:
            return do_VFLOGH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFABSH16:
            return do_VFABSH16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFMAX16:
            return do_VFMAX16(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFEXTS32L:
            return do_VFEXTS32L(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFEXTS32H:
            return do_VFEXTS32H(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFEXTH16LL:
            return do_VFEXTH16LL(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFEXTH16LH:
            return do_VFEXTH16LH(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFEXTH16HL:
            return do_VFEXTH16HL(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFEXTH16HH:
            return do_VFEXTH16HH(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VMOV_VMAC:
            return do_VMOV(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VMOVI_VMAC:
            return do_VMOVI(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFCMPED:
            return do_VFCMPED(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());    
        case VFCMPES32:
            return do_VFCMPES32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());  
        case VFCMPGD:
            return do_VFCMPGD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());   
        case VFCMPGS32:
            return do_VFCMPGS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFCMPLD:
            return do_VFCMPLD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id()); 
        case VFCMPLS32:
            return do_VFCMPLS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id()); 
        case VFDINT:
            return do_VFDINT(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFSINT32:
            return do_VFSINT32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFDTRU:
            return do_VFDTRU(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());   
        case VFSTRU32:
            return do_VFSTRU32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFINTD:
            return do_VFINTD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFINTDU:
            return do_VFINTDU(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFINTS32:
            return do_VFINTS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFINTSU32:
            return do_VFINTSU32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFDPSP32:
            return do_VFDPSP32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id(),
                                    static_cast<register_operand*>(vmac_instr->get_operands(2))->get_reg_id());
        case VFSPDP32T:
            return do_VFSPDP32T(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFSPHDP32T:
            return do_VFSPHDP32T(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFMAND:
            return do_VFMAND(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFMANS32:
            return do_VFMANS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFLOGD:
            return do_VFLOGD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFLOGS32:
            return do_VFLOGS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFABSD:
            return do_VFABSD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFABSS32:
            return do_VFABSS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFRSQD:
            return do_VFRSQD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFRSQS32:
            return do_VFRSQS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFRCPD:
            return do_VFRCPD(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
        case VFRCPS32:
            return do_VFRCPS32(static_cast<register_operand*>(vmac_instr->get_operands(0))->get_reg_id(),
                                static_cast<register_operand*>(vmac_instr->get_operands(1))->get_reg_id());
            
        //TODO:将所有操作的实际执行逻辑补全
    }
}